"""
AI Web MCP工具数据库模型
"""

import json
from datetime import datetime
from typing import Optional, Dict, Any, List

from sqlalchemy import String, Integer, DateTime, JSON, Index
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy.sql import func

from config.database import Base


class AIWebMCPToolsModel(Base):
    """AI Web MCP工具数据库模型"""
    __tablename__ = "ai_web_mcp_tools"

    # 主键
    id: Mapped[int] = mapped_column(
        Integer,
        primary_key=True,
        autoincrement=True,
        comment="主键ID"
    )

    # 基本字段
    mcp_name: Mapped[str] = mapped_column(
        String(200),
        nullable=False,
        comment="MCP工具名称"
    )

    description: Mapped[Optional[str]] = mapped_column(
        String(500),
        nullable=True,
        comment="MCP工具描述"
    )

    status: Mapped[int] = mapped_column(
        Integer,
        nullable=False,
        default=0,
        comment="接入状态（0=测试中,1=已上线,2=已下线）"
    )

    access_type: Mapped[int] = mapped_column(
        Integer,
        nullable=False,
        comment="接入类型（1=API,2=本地工具）"
    )

    # 文档URL字段
    doc_url: Mapped[Optional[str]] = mapped_column(
        String(500),
        nullable=True,
        comment="文档URL"
    )

    # JSON配置字段
    json_schema: Mapped[Optional[str]] = mapped_column(
        JSON,
        nullable=True,
        comment="JSON配置内容"
    )

    # 时间字段
    created_at: Mapped[datetime] = mapped_column(
        DateTime,
        nullable=False,
        default=func.current_timestamp(),
        comment="创建时间"
    )
    updated_at: Mapped[datetime] = mapped_column(
        DateTime,
        nullable=False,
        default=func.current_timestamp(),
        onupdate=func.current_timestamp(),
        comment="更新时间"
    )

    # 索引和约束
    __table_args__ = (
        Index('idx_mcp_name', 'mcp_name'),
        Index('idx_status', 'status'),
        Index('idx_access_type', 'access_type'),
        Index('idx_created_at', 'created_at'),
        Index('idx_mcp_name_unique', 'mcp_name', unique=True),  # MCP工具名称唯一
        {"comment": "AI Web MCP工具管理表"}
    )

    def __init__(self, **kwargs):
        """初始化方法"""
        # 处理json_schema参数
        if 'json_schema' in kwargs:
            json_schema = kwargs.pop('json_schema')
            super().__init__(**kwargs)
            self.set_json_schema(json_schema)
        else:
            super().__init__(**kwargs)

    def __repr__(self):
        return f"<AIWebMCPToolsModel(id={self.id}, mcp_name='{self.mcp_name}', status={self.status}, access_type={self.access_type})>"

    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            "id": self.id,
            "mcp_name": self.mcp_name,
            "description": self.description,
            "status": self.status,
            "access_type": self.access_type,
            "doc_url": self.doc_url,
            "json_schema": self.get_json_schema(),
            "created_at": self.created_at.isoformat() if self.created_at else None,
            "updated_at": self.updated_at.isoformat() if self.updated_at else None
        }

    def get_json_schema(self) -> Optional[Dict[str, Any]]:
        """获取JSON配置"""
        if isinstance(self.json_schema, str):
            try:
                return json.loads(self.json_schema)
            except (json.JSONDecodeError, TypeError):
                return None
        elif isinstance(self.json_schema, dict):
            return self.json_schema
        return self.json_schema

    def set_json_schema(self, schema: Optional[Dict[str, Any]]) -> None:
        """设置JSON配置"""
        if schema is None:
            self.json_schema = None
        elif isinstance(schema, dict):
            self.json_schema = json.dumps(schema, ensure_ascii=False) if schema else None
        elif isinstance(schema, str):
            # 如果已经是JSON字符串，验证后直接设置
            try:
                json.loads(schema)  # 验证JSON有效性
                self.json_schema = schema
            except (json.JSONDecodeError, TypeError):
                self.json_schema = None
        else:
            # 其他类型，尝试转换为JSON
            try:
                self.json_schema = json.dumps(schema, ensure_ascii=False)
            except (TypeError, ValueError):
                self.json_schema = None

    def get_status_display(self) -> str:
        """获取状态显示文本"""
        status_map = {
            0: "测试中",
            1: "已上线",
            2: "已下线"
        }
        return status_map.get(self.status, "未知状态")

    def get_access_type_display(self) -> str:
        """获取接入类型显示文本"""
        type_map = {
            1: "API接入",
            2: "本地工具"
        }
        return type_map.get(self.access_type, "未知类型")

    def is_online(self) -> bool:
        """判断是否已上线"""
        return self.status == 1

    def is_testing(self) -> bool:
        """判断是否在测试中"""
        return self.status == 0

    def is_discontinued(self) -> bool:
        """判断是否已下线"""
        return self.status == 2

    def is_api_access(self) -> bool:
        """判断是否为API接入"""
        return self.access_type == 1

    def is_local_tool(self) -> bool:
        """判断是否为本地工具"""
        return self.access_type == 2

    def update_status(self, new_status: int) -> None:
        """更新状态"""
        if new_status not in [0, 1, 2]:
            raise ValueError(f"无效的状态值: {new_status}，必须是 0, 1, 2 中的一个")

        self.status = new_status
        self.updated_at = datetime.now()

    def update_access_type(self, new_access_type: int) -> None:
        """更新接入类型"""
        if new_access_type not in [1, 2]:
            raise ValueError(f"无效的接入类型: {new_access_type}，必须是 1, 2 中的一个")

        self.access_type = new_access_type
        self.updated_at = datetime.now()

    def update_json_schema(self, schema: Optional[Dict[str, Any]]) -> None:
        """更新JSON配置"""
        self.set_json_schema(schema)
        self.updated_at = datetime.now()

    def set_online(self) -> None:
        """设置为已上线状态"""
        self.update_status(1)

    def set_testing(self) -> None:
        """设置为测试中状态"""
        self.update_status(0)

    def set_discontinued(self) -> None:
        """设置为已下线状态"""
        self.update_status(2)

    def validate_json_schema(self) -> bool:
        """验证JSON配置的有效性"""
        try:
            schema = self.get_json_schema()
            if schema is not None and not isinstance(schema, dict):
                return False
            return True
        except Exception:
            return False

    def get_schema_field(self, field_name: str, default_value: Any = None) -> Any:
        """从JSON配置中获取指定字段值"""
        schema = self.get_json_schema()
        if schema and isinstance(schema, dict):
            return schema.get(field_name, default_value)
        return default_value

    def set_schema_field(self, field_name: str, field_value: Any) -> None:
        """在JSON配置中设置指定字段值"""
        schema = self.get_json_schema() or {}
        schema[field_name] = field_value
        self.set_json_schema(schema)
        self.updated_at = datetime.now()

    def remove_schema_field(self, field_name: str) -> bool:
        """从JSON配置中移除指定字段"""
        schema = self.get_json_schema()
        if schema and isinstance(schema, dict) and field_name in schema:
            del schema[field_name]
            self.set_json_schema(schema)
            self.updated_at = datetime.now()
            return True
        return False

    def get_schema_keys(self) -> List[str]:
        """获取JSON配置中的所有字段名"""
        schema = self.get_json_schema()
        if schema and isinstance(schema, dict):
            return list(schema.keys())
        return []

    def has_schema_field(self, field_name: str) -> bool:
        """检查JSON配置中是否包含指定字段"""
        schema = self.get_json_schema()
        if schema and isinstance(schema, dict):
            return field_name in schema
        return False

    def get_mcp_summary(self) -> Dict[str, Any]:
        """获取MCP工具摘要信息"""
        return {
            "id": self.id,
            "mcp_name": self.mcp_name,
            "description": self.description,
            "status": self.status,
            "status_display": self.get_status_display(),
            "access_type": self.access_type,
            "access_type_display": self.get_access_type_display(),
            "doc_url": self.doc_url,
            "has_json_schema": self.json_schema is not None and self.json_schema != "",
            "schema_keys_count": len(self.get_schema_keys()),
            "created_at": self.created_at.isoformat() if self.created_at else None,
            "updated_at": self.updated_at.isoformat() if self.updated_at else None
        }

    def clone_config(self) -> Dict[str, Any]:
        """克隆MCP工具配置（用于复制工具）"""
        return {
            "mcp_name": f"{self.mcp_name}_copy",
            "description": self.description,
            "status": 0,  # 新复制的工具默认为测试状态
            "access_type": self.access_type,
            "doc_url": self.doc_url,
            "json_schema": self.get_json_schema()
        }

    @classmethod
    def create_from_dict(cls, data: Dict[str, Any]) -> 'AIWebMCPToolsModel':
        """从字典创建实例"""
        return cls(**data)

    @classmethod
    def get_all_status_options(cls) -> List[Dict[str, Any]]:
        """获取所有状态选项"""
        return [
            {"value": 0, "label": "测试中"},
            {"value": 1, "label": "已上线"},
            {"value": 2, "label": "已下线"}
        ]

    @classmethod
    def get_all_access_type_options(cls) -> List[Dict[str, Any]]:
        """获取所有接入类型选项"""
        return [
            {"value": 1, "label": "API接入"},
            {"value": 2, "label": "本地工具"}
        ]

    @classmethod
    def validate_status_value(cls, status: int) -> bool:
        """验证状态值是否有效"""
        return status in [0, 1, 2]

    @classmethod
    def validate_access_type_value(cls, access_type: int) -> bool:
        """验证接入类型值是否有效"""
        return access_type in [1, 2]
